home *** CD-ROM | disk | FTP | other *** search
- /*
- MOD 08-07-87 MAZ - fix clobber of "i" within chunks loop that caused infinite writes
- MOD 07-12-87 MAZ - file converter RIFF output routines
- */
- #include <Quickdraw.h>
- #include <WindowMgr.h>
- #include <EventMgr.h>
- #include <MenuMgr.h>
- #include <ControlMgr.h>
- #include <DialogMgr.h>
- #include <FileMgr.h>
- #include <StdFilePkg.h>
- #include "MAZlib.h"
- #include "RIFF.h"
-
- extern bool init_io();
-
- /* MAZlib externs */
- extern bool output_file_name();
- extern short global_volrefnum;
- extern long disk_bytes_free();
-
- /* the stuff read in */
- extern unsigned char *body[4];
- extern short nrows;
- extern short ncols;
- extern short nsamples;
- extern short storage_type;
- extern short dpi;
- extern bool uncompressed;
- extern unsigned char *transfer_table;
-
- /* globals for custom standard file dialogs */
- SFTypeList otherTypeList;
-
- /* forward declarations */
- short save_open();
- short save_data();
-
- /* save picture to prompted name */
- bool save_as_RIFF(suggested, desired_nsamples)
- char *suggested;
- short desired_nsamples;
- {
- short i;
- char filename[256];
-
- while (output_file_name("Save As:", filename, suggested))
- {
- strcpy(suggested, filename);
- /* do the save */
- i = save_data(global_volrefnum, filename, desired_nsamples);
- /* and exit if all went well */
- if (i == 0)
- return(true);
- /* not enough memory to allocate buffers for save */
- /* user doesn't get another chance to do it */
- if (i == 3)
- return(false);
- /* otherwise, try again... */
- }
- /* user cancelled */
- return(false);
- }
-
- /* open RIFF file for writing */
- static short save_open(refnum, filename, bytecount, io)
- short refnum;
- char *filename;
- long bytecount;
- ioParam *io;
- {
- bool save_finder_info;
- FileParam fparm;
-
- /* get Pascal filename */
- CtoPstr(filename);
- /* get info on existing output file of same name (if any) */
- fparm.ioNamePtr = (StringPtr)filename;
- fparm.ioVRefNum = refnum;
- fparm.ioFVersNum = 0; /* normal version */
- fparm.ioFDirIndex = 0; /* use filename and vrefnum */
- fparm.ioResult = 1;
- PBGetFInfo(&fparm, false);
- if (fparm.ioResult >= 0)
- {
- /* file exists, reduce bytecount needed by its size */
- bytecount -= fparm.ioFlPyLen;
- /* save old file's finder info if the same type */
- save_finder_info = (fparm.ioFlFndrInfo.fdType == 'RIFF' &&
- fparm.ioFlFndrInfo.fdCreator == 'FSPE');
- }
- else
- save_finder_info = false;
- /* make sure there is enough room on disk for file */
- if (bytecount > disk_bytes_free(refnum))
- {
- /* undo damage to filename */
- PtoCstr(filename);
- return(1); /* not enough disk space for RIFF file */
- }
- /* delete and recreate file */
- io->ioNamePtr = (StringPtr)filename;
- io->ioVRefNum = refnum;
- io->ioVersNum = 0; /* normal version */
- PBDelete(io, false);
- PBCreate(io, false);
- /* test for preexisting file */
- if (!save_finder_info)
- {
- /* get file info for new file */
- fparm.ioFDirIndex = 0; /* use filename and vrefnum */
- PBGetFInfo(&fparm, false);
- }
- /* set file type and creator for new file */
- fparm.ioFlFndrInfo.fdType = 'RIFF';
- fparm.ioFlFndrInfo.fdCreator = 'FSPE';
- PBSetFInfo(&fparm, false);
- /* open the file */
- io->ioPermssn = fsWrPerm; /* writing */
- io->ioMisc = null;
- io->ioResult = 1;
- PBOpen(io, false);
- /* restore the filename */
- PtoCstr(filename);
- /* test for open failed */
- if (io->ioResult < 0)
- return(2); /* open failed */
- /* good return */
- return(0);
- }
-
- /* save the RIFF file */
- static short save_data(refnum, filename, desired_nsamples)
- short refnum;
- char *filename;
- short desired_nsamples;
- {
- short i, j, flat, nchunks, nsamples_rounded;
- long estimate, chunksize;
- register unsigned char *p;
- register long l;
- short *huffbuff;
- RIFF_header Rheader;
- long save[4];
- char str[32];
- ioParam writeparm;
- unsigned char table[256], dtable[256];
-
- /* allocate temporary buffer */
- huffbuff = (short *)NewPtr((long)ncols * 2 + 2L);
- if (huffbuff == null)
- return(3); /* not enough memory */
- /* generate a pessimistic disk size estimate */
- nsamples_rounded = (desired_nsamples + 1) & ~1;
- flat = (4 + ncols) & ~1;
- switch (storage_type)
- {
- case st_gray:
- case st_vlt:
- nchunks = 1;
- break;
- case st_rgb:
- case st_hsv:
- case st_cmy:
- nchunks = 3;
- break;
- case st_cmyk:
- nchunks = 4;
- break;
- }
- estimate = (long)flat*(long)nrows*(long)nchunks
- + sizeof(RIFF_header) + nsamples_rounded;
- /* open the RIFF file for writing */
- i = save_open(refnum, filename, estimate, &writeparm);
- /* if we got an error, clean up and exit */
- if (i != 0)
- {
- DisposPtr(huffbuff);
- return(i);
- }
- /* init for I/O */
- if (!init_io(0L))
- {
- /* can't get an I/O buffer */
- /* close the file */
- PBClose(&writeparm, false);
- DisposPtr(huffbuff);
- return(3); /* not enough memory */
- }
- init_write(&writeparm);
- /* make up a riff file header */
- fillbuffer(&Rheader, sizeof(RIFF_header), 0);
- Rheader.revnum = RIFF_rev1_1;
- Rheader.nrows = nrows;
- Rheader.ncols = ncols;
- Rheader.flags = hf_transfer;
- if (uncompressed)
- Rheader.flags |= uncompressed;
- Rheader.storage_type = storage_type;
- Rheader.nsamples = desired_nsamples;
- /* write out a null chunks field (and later fix it up) */
- Rheader.chunks[0] = 0;
- Rheader.chunks[1] = 0;
- Rheader.chunks[2] = 0;
- Rheader.chunks[3] = 0;
- Rheader.resolution = dpi;
- for (i = 0; i < 32; i++)
- Rheader.reserved[i] = 0;
- /* write out the riff header */
- putbytes(&writeparm, &Rheader, (long)sizeof(RIFF_header));
- for (i = 0; i < desired_nsamples; i++)
- dtable[i] = i;
- putbytes(&writeparm, dtable, (long)desired_nsamples);
- /* pass 256-sample data through a table so it can be a desired number of samples */
- for (i = 0; i < 256; i++)
- table[i] = ((long)(transfer_table[i]) * (long)(desired_nsamples-1) + 128) / 255;
- chunksize = (long)nrows * (long)ncols;
- for (i = 0; i < nchunks; i++)
- {
- /* adjust file output alignment to be even */
- flushbytes(&writeparm);
- if (writeparm.ioPosOffset&1)
- {
- j = 0;
- putbytes(&writeparm, &j, 1L); /* do even file address alignment */
- }
- flushbytes(&writeparm);
- save[i] = writeparm.ioPosOffset;
- /* run all of the data threough the table, to coerce it to a given number of samples */
- for (l = 0, p = body[i]; l < chunksize; l++, p++)
- *p = table[*p];
- /* test for compressed output */
- if (uncompressed)
- putbytes(&writeparm, body[i], chunksize);
- else
- COMPoutput(&writeparm, body[i], huffbuff);
- }
- flushbytes(&writeparm);
- /* free I/O buffer */
- term_io();
- /* go back to the beginning of the file and update the header */
- for (i = 0; i < nchunks; i++)
- Rheader.chunks[i] = save[i];
- writeparm.ioPosMode = fsFromStart;
- writeparm.ioPosOffset = 0L;
- PBSetFPos(&writeparm, null);
- writeparm.ioBuffer = (char *)&Rheader;
- writeparm.ioReqCount = sizeof(RIFF_header);
- PBWrite(&writeparm, null);
- /* close the file */
- PBClose(&writeparm, false);
- /* flush the volume */
- PBFlshVol(&writeparm, false);
- DisposPtr(huffbuff);
- return(0); /* no error */
- }
-